import 'dart:convert';

import 'package:im_app/im/service/ImGroupService.dart';
import 'package:im_app/im/util/DbUtil.dart';
import 'package:logger/logger.dart';
import 'package:sqflite/sqflite.dart';

import '../../dao/ImSessionDao.dart';
import '../../pojo/ImPojo.dart';
import '../../util/ImCacheFactory.dart';
import '../../util/ImSingleton.dart';
import '../../util/UiUtil.dart';
import '../dto/business/SendData.dart';
import 'InitRouter.dart';

class GroupConsumerRouter {

  final _logger = Logger(printer: PrettyPrinter(),);

  // final _groupService = ImGroupService();
  // final _sessionDao = ImSessionDao();

  void initCallback(Map<String, CallbackData> callbackMap) {
    callbackMap.putIfAbsent("serverRedirectGroupCreate", ()=> CallbackData(decodeFunction: GroupCreateReq.fromJson, doFunction: receiveGroupCreate));
    callbackMap.putIfAbsent("serverRedirectGroupAdd", ()=> CallbackData(decodeFunction: GroupAddReq.fromJson, doFunction: receiveGroupAdd));
    callbackMap.putIfAbsent("serverRedirectGroupExit", ()=> CallbackData(decodeFunction: GroupExitReq.fromJson, doFunction: receiveGroupExit));
    callbackMap.putIfAbsent("serverRedirectGroupDel", ()=> CallbackData(decodeFunction: GroupDelReq.fromJson, doFunction: receiveGroupDel));
    callbackMap.putIfAbsent("serverSendGroupInfo", ()=> CallbackData(decodeFunction: ServerSendGroupInfoReq.fromJson, doFunction: receiveGroupInfo));
  }

  void receiveGroupCreate(GroupCreateReq groupCreateReq) async {
    _logger.i("receive group create: " + jsonEncode(groupCreateReq));
    int time = DateTime.now().difference(groupCreateReq.createDateTime!).inMilliseconds;
    _logger.i("收到服务端转发群创建信息，receive group create time: $time, data: ${groupCreateReq}", );
    String userId = ImSingleton.getInstance().session.userId!;
    var session;

    var database = await DbUtil.getDatabase();
    try {
      session = await _buildGroup(userId, groupCreateReq);
      final groupService = ImGroupService();
      await groupService.createImGroup(session);
    } finally {
      DbUtil.close(database);
    }


    UiUtil.uiAddSession(session!);
    _logger.i("receive group create end");
  }

  void receiveGroupAdd(GroupAddReq groupAddReq) async {
    _logger.i("receive group add: " + jsonEncode(groupAddReq));
    int time = DateTime.now().difference(groupAddReq.createDateTime!).inMilliseconds;
    _logger.i("收到服务端转发进群信息，receive group add time: $time, data: ${groupAddReq}", );
    String userId = ImSingleton.getInstance().session.userId!;

    ImSession? session = null;
    var groupService = ImGroupService();
    ImGroup? imGroup = await groupService.getByCodeAndUserId(groupAddReq.groupId, userId);
    if (imGroup == null) {
      session = await _buildGroup(userId, groupAddReq);

      await groupService.createImGroup(session);
    } else {
      session = await groupService.addToGroup(userId, groupAddReq);
    }

    UiUtil.uiShowSession(session!);
    _logger.i("receive group add end");
  }

  void receiveGroupExit(GroupExitReq groupExitReq) async {
    _logger.i("receive group exit: " + jsonEncode(groupExitReq));
    int time = DateTime.now().difference(groupExitReq.createDateTime!).inMilliseconds;
    _logger.i("收到服务端转发退群信息，receive group exit time: $time, data: ${groupExitReq}", );
    String userId = ImSingleton.getInstance().session.userId!;

    var groupService = ImGroupService();
    var session = await groupService.exitGroup(userId, groupExitReq);
    _logger.i("receive group exit end");
  }

  void receiveGroupDel(GroupDelReq groupDelReq) async {
    _logger.i("receive group create: " + jsonEncode(groupDelReq));
    int time = DateTime.now().difference(groupDelReq.createDateTime!).inMilliseconds;
    _logger.i("收到服务端转发删群信息，receive group delete time: $time, data: ${groupDelReq}", );
    String userId = ImSingleton.getInstance().session.userId!;

    var groupService = ImGroupService();
    var session = await groupService.delGroup(userId, groupDelReq);
    UiUtil.uiShowSession(session!);

    _logger.i("receive group create end");
  }

  void receiveGroupInfo(ServerSendGroupInfoReq serverGroupInfoReq) async {
    _logger.i("receive group info: " + jsonEncode(serverGroupInfoReq));
    int time = DateTime.now().difference(serverGroupInfoReq.createDateTime!).inMilliseconds;
    _logger.i("收到服务端群信息，receive group delete time: $time, data: ${serverGroupInfoReq}", );
    String userId = ImSingleton.getInstance().session.userId!;

    final groupService = ImGroupService();
    final sessionDao = ImSessionDao();
    await groupService.saveOrUpdates(userId, [serverGroupInfoReq.groupInfoItem], true);

    var session = await sessionDao.getByGroupCodeAndUserId(serverGroupInfoReq.groupInfoItem.groupId, userId);
    UiUtil.uiShowSession(session!);
    _logger.i("receive group info end");
  }

  Future<ImSession> _buildGroup(String userId, GroupCreateReq groupCreateReq) async {
    List<ImUser> users = <ImUser>[];
    for (var userId in groupCreateReq.userIdSet) {
      ImUser? user = await ImCacheFactory.getInstance().getImUser(userId);
      users.add(user!);
    }
    final groupService = ImGroupService();
    var session = groupService.buildImGroup(userId, users);
    session.groupCode = groupCreateReq.groupId;
    session.name = groupCreateReq.groupName;
    session.group!.code = groupCreateReq.groupId;
    session.group!.description = groupCreateReq.groupDesc;
    session.group!.name = groupCreateReq.groupName;
    return session;
  }
}